package com.spring.factory.impl;


import com.spring.factory.ObjectFactory;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 名不副实，这玩意不能叫SingletonObjects ， 原型对象也从这里面走过一遭
 */
public class SingletonObjects {
	/**
	 * 一级缓存
	 */
	private final ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
	
	/**
	 * 二级缓存
	 */
	private final HashMap<String, Object> earlySingletonObjects = new HashMap<>(16);
	
	/**
	 * 三级缓存
	 */
	private final HashMap<String, ObjectFactory<?>> objectFactories = new HashMap<>(16);
	
	/**
	 * 创建中的对象名字  beanName ，在这里面就表示对象正处于创建过程中
	 */
	private final Set<String> inCreating = new HashSet<>(16);
	
	/**
	 * 创建完成的单例对象名字 ,只有单例对象进这里！！  原型对象不要进单例池，也不要进这里面
	 */
	private final Set<String> finishedCreate = new HashSet<>();
	
	
	/**
	 * 从一级缓存获取
	 */
	public Object getSingletonObject(String beanName) {
		return singletonObjects.get(beanName);
	}
	
	/**
	 * 从二级缓存获取
	 */
	public Object getEarlySingletonObject(String beanName) {
		return earlySingletonObjects.get(beanName);
	}
	
	/**
	 * 从三级缓存获取
	 */
	public ObjectFactory<?> getObjectFactory(String beanName) {
		return objectFactories.get(beanName);
	}
	
	
	/**
	 * 添加到单例池中
	 */
	public void addSingleton(String beanName, Object singletonObject) {
		if (this.singletonObjects.contains(beanName)) {
			throw new RuntimeException("单例bean 重复添加到单例池");
		}
		
		this.singletonObjects.put(beanName, singletonObject);
		this.finishedCreate.add(beanName);
	}
	
	/**
	 * 是否正在创建中
	 */
	public boolean isInCreating(String beanName) {
		return this.inCreating.contains(beanName);
	}
	
	/**
	 * 是否结束创建
	 */
	public boolean isFinishCreated(String beanName) {
		return this.finishedCreate.contains(beanName);
	}
	
	/**
	 * 标记创建中
	 */
	public void remarkInCreating(String beanName) {
		this.inCreating.add(beanName);
	}
	
	/**
	 * 标记创建结束
	 */
	public void remarkCreateFinished(String beanName) {
		this.inCreating.remove(beanName);
	}
	
	/**
	 * 加入一个工厂对象到三级缓存
	 */
	public void addObjectFactory(String beanName, ObjectFactory<?> factory) {
		objectFactories.put(beanName, factory);
	}
	
	/**
	 * 从三级缓存中移除
	 */
	public void removeObjectFactory(String beanName) {
		objectFactories.remove(beanName);
	}
	
	/**
	 * 加入二级缓存
	 */
	public void addEarlyObject(String beanName, Object bean) {
		if (earlySingletonObjects.containsKey(beanName)) {
			throw new RuntimeException("二级缓存重复添加！");
		}
		earlySingletonObjects.put(beanName, bean);
	}
	
	public void removeEarlyObject(String beanName) {
		earlySingletonObjects.remove(beanName);
	}
	
	
	// 移除单例bean ，看情况如何这个是原型bean 的话，这样做不符合类名字定义了 ？？
	protected void removeSingleton(String beanName) {
		this.singletonObjects.remove(beanName);
		this.earlySingletonObjects.remove(beanName);
		this.objectFactories.remove(beanName);
		
		this.inCreating.remove(beanName);
	}
}
